package;

import flixel.system.FlxSound;
import flixel.util.FlxColor;
import flixel.group.FlxGroup.FlxTypedGroup;
import flixel.FlxG;
import flixel.tile.FlxTilemap;
import flixel.addons.editors.ogmo.FlxOgmo3Loader;
import flixel.FlxState;

using flixel.util.FlxSpriteUtil;

class PlayState extends FlxState
{
	var player:Player;
	var map:FlxOgmo3Loader;
	var walls:FlxTilemap;

	var coinSound:FlxSound;

	var hud:HUD;
	var money:Int = 0;
	var health:Int = 3;

	var ending:Bool;
	var won:Bool;

	var inCombat:Bool = false;
	var CombatHUD:CombatHUD;  

	var coins:FlxTypedGroup<Coin>;
	var enemies:FlxTypedGroup<Enemy>;

	function placeEntities(entity:EntityData) {
		if (entity.name == "player") {
			player.setPosition(entity.x, entity.y);
		} else if (entity.name == "coin") {
			coins.add(new Coin(entity.x + 4, entity.y + 4));
		} else if (entity.name == "enemy") {
			enemies.add(new Enemy(entity.x + 4, entity.y, REGULAR));
		} else if (entity.name == "boss") {
			enemies.add(new Enemy(entity.x + 4, entity.y, BOSS));
		}
	}

	override public function create()
	{
		hud = new HUD();
		add(hud);

		coinSound = FlxG.sound.load(AssetPaths.coin__wav);

		super.create();

		map = new FlxOgmo3Loader(AssetPaths.turnBasedRPG__ogmo, AssetPaths.room_001__json);
		
		walls = map.loadTilemap(AssetPaths.tiles__png, "walls");
		walls.follow();
		walls.setTileProperties(1, NONE);
		walls.setTileProperties(2, ANY);
		add(walls);
	
		coins = new FlxTypedGroup<Coin>();
		add(coins);

		enemies = new FlxTypedGroup<Enemy>();
		add(enemies);

		player = new Player();
		add(player);
		map.loadEntities(placeEntities, "entities");
		
		CombatHUD = new CombatHUD();
		add(CombatHUD);
		
		FlxG.camera.follow(player, TOPDOWN, 1);
	}

	function playerTouchCoin(player:Player, coin:Coin) {
		if (player.alive && player.exists && coin.alive && coin.exists) {
			coinSound.play(true);
			coin.kill();
		}

		money++;
		hud.updateHUD(health, money);
	}

	function playerTouchEnemy(player:Player, enemy:Enemy)
	{
		if (player.alive && player.exists && enemy.alive && enemy.exists && !enemy.isFlickering())
		{
			startCombat(enemy);
		}
	}

	function startCombat(enemy:Enemy)
	{
		inCombat = true;
		player.active = false;
		enemies.active = false;
		CombatHUD.initCombat(health, enemy);
	}

	function doneFadeOut()
	{
		FlxG.switchState(new GameOverState(won, money));
	}

	override public function update(elapsed:Float)
	{
		super.update(elapsed);
		if (ending)
		{
			return;
		}

		if (!CombatHUD.visible)
		{
			health = CombatHUD.playerHealth;
			hud.updateHUD(health, money);
			if (CombatHUD.outcome == DEFEAT)
			{
				ending = true;
				FlxG.camera.fade(FlxColor.BLACK, 0.33, false, doneFadeOut);
			}
			else
			{
				if (CombatHUD.outcome == VICTORY)
				{
					CombatHUD.enemy.kill();
					if (CombatHUD.enemy.type == BOSS)
					{
						won = true;
						ending = true;
						FlxG.camera.fade(FlxColor.BLACK, 0.33, false, doneFadeOut);
					}
				}
				else
				{
					CombatHUD.enemy.flicker();
				}
				inCombat = false;
				player.active = true;
				enemies.active = true;
			}
		}

	}
	
	function checkEnemyVision(enemy:Enemy)
	{
		if (walls.ray(enemy.getMidpoint(), player.getMidpoint()))
		{
			enemy.seesPlayer = true;
			enemy.playerPosition = player.getMidpoint();
		}
		else
		{
			enemy.seesPlayer = false;
		}
	}
}
